package com.cskaoyan.javse.object._1getClass;

/**
 * @description: getClass方法
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * getClass方法
 * 1.方法声明: public final native Class<?> getClass();
 *      解释:
 *      首先它的访问权限修饰符是public,它被子类继承后,可以在任何地方调用
 *      final修饰它,表示它无法被重写
 *      native表示该方法是一个本地方法,不是一个普通方法.本地方法指的是借助C/C++或其它语言实现的方法
 *          所以本地方法是没有方法体的,并且它的调用要占用本地方法栈,而不是jvm栈
 *      Class<?>是返回值类型,表示该方法需要返回一个Class对象,<?>表示泛型,关于泛型后面会详细讲
 *          java的泛型是"伪泛型",直接忽略泛型,代码照样正常运行
 *      getClass是方法名
 *      ()表示形参列表,该方法不需要参数
 *
 * 2.作用:
 *      通过一个本地方法实现,获取Class对象
 *      什么是Class对象?Class是什么?它又有什么作用?
 *      该方法的返回对象是表示此对象(调用getClass方法的对象)运行时类的 Class 对象
 *      Class对象就是运行时类对象
 *      什么是运行时类?
 *
 * 首先创建Student对象,触发Student类的类加载
 * 在类加载过程中,jvm通过读取该类的二进制字节码
 * 文件,了解该类型
 * 但是在程序的运行期间,程序员是不知道类型信息
 * 但是有些时候在程序运行期间,了解类型信息也是
 * 程序员需要完成的事情
 *
 * 于是: JVM在类加载一个类的同时,在堆上会自动生成
 * 该类的运行时类对象,也就是Class对象
 * Class对象当中,包含了该类的所有类型信息
 * (比如类名是啥,在哪个包,有哪些方法,有哪些变量等)
 *
 * 于是程序员在程序的运行时期只需要获取Class对象
 * 就能够获取类型信息了
 * 这就是Class对象的作用
 *
 * 使用getClass方法的注意事项:
 *      1.getClass方法只是获取Class对象,只是让一个引用指向Class对象,能够使用Class对象
 *          但是Class对象是在类加载过程中由jvm完成创建的
 *          后面我们还会学习几种获取Class对象的方式,可以不创建对象也能获取Class对象
 *
 *     2.一个类的类加载只有一次,同一个类型的运行时Class对象也只有一个
 *          不同类型的Class对象肯定不是同一个对象
 *          这一点是非常重要的,用这个特点,可以判断两个引用所指向的对象是否是同一个类型的对象
 *
 *     3.运行时类Class对象只有一个,而类的对象可以有无数个
 *          很多时候我们把类的运行时类对象,称之为"类对象"
 *          而具体的类的对象,称之为"类的对象"
 *
 *     4.Class类对象是反射的基础
 *          反射实际上就是Class类的API的调用
 *          Class类中两个成员方法:
 *          - getName()
 *   -          获取类的全限定类名
 * -          getSimpleName()
 *   -          获取类名
 *
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        Student s2 = new Student();
        Class stuClazz = s.getClass();
        Class stuClazz2 = s2.getClass();
        System.out.println(stuClazz == stuClazz2); //比较的是 是否指向同一个对象

        Teacher t = new Teacher();
        Class teacherClazz = t.getClass();
        System.out.println(teacherClazz == stuClazz);

        System.out.println(teacherClazz.getName()); //获取全限定类名
        System.out.println(teacherClazz.getSimpleName()); //获取简单类名
    }
}

class Student  {

}

class Teacher {
}